package com.qxl.forest.business.controller;

import com.qxl.forest.business.service.UserService;
import com.qxl.forest.core.annotion.BussinessLog;
import com.qxl.forest.core.annotion.Permission;
import com.qxl.forest.common.constants.Const;
import com.qxl.forest.common.constants.RequestParams;
import com.qxl.forest.common.constants.factory.ConstantFactory;
import com.qxl.forest.business.persistence.dao.UserDao;
import com.qxl.forest.business.persistence.entity.ShiroUser;
import com.qxl.forest.business.persistence.entity.User;
import com.qxl.forest.common.constants.state.UserStatus;
import com.qxl.forest.common.util.ToolUtil;
import com.qxl.forest.core.shiro.ShiroKit;
import com.qxl.forest.exception.BizExceptionEnum;
import com.qxl.forest.exception.BussinessException;
import com.qxl.forest.util.CommRes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * @Author: qiuxinlin
 * @Dercription:
 * @Date: 2017/11/23
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserDao userDao;
    @Autowired
    UserService userService;

    /**
     * 添加用户
     *
     * @return
     */
    @PostMapping(value = "/add")
    @Permission(Const.ADMIN_NAME)
    @BussinessLog(value = "添加用户", key = "user")
    public CommRes add(@RequestBody User user) {
        //判断账号是否重复
        User theUser = userDao.findByAccount(user.getAccount());
        if (theUser != null) {
            throw new BussinessException(BizExceptionEnum.USER_ALREADY_REG);
        }
        //完善账号信息
        user.setSalt(ShiroKit.getRandomSalt(5));
        user.setPassword(ShiroKit.md5(user.getPassword(), user.getSalt()));
        user.setStatus(UserStatus.OK.getCode());
        user.setCreatetime(new Date());
        userDao.save(user);
        return CommRes.successRes();
    }

    /**
     * 查询用户列表
     *
     * @return
     */
    @PostMapping(value = "/get")
    @Permission
    //@Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.USERS_NAME + "'+#requestParams.pageNumber")
    public CommRes getAll(@RequestBody RequestParams requestParams) {
        if (requestParams.getPageSize() == 0) {
            throw new BussinessException(BizExceptionEnum.REQUEST_NULL);
        }
        PageRequest pageRequest = new PageRequest(requestParams.getPageNumber(), requestParams.getPageSize());
        Page users = userDao.findAll(pageRequest);
        ConstantFactory constantFactory = (ConstantFactory) ConstantFactory.me();
        for (User user : (List<User>) users.getContent()) {
            String roleNames = constantFactory.getRoleName(user.getRoleid());
            String deptName = constantFactory.getDeptName(user.getDeptid());
            user.setRoleNames(roleNames);
            user.setDeptName(deptName);
        }
        return CommRes.success(users);
    }

    /**
     * 条件查询用户列表
     *
     * @return
     */
    @PostMapping(value = "/query")
    @Permission
    public List queryUser(@RequestBody RequestParams requestParams) {
        Integer deptId = ShiroKit.getUser().getDeptId();
        requestParams.setDeptid(deptId);
        return userService.queryUser(requestParams);
    }

    /**
     * 修改用户
     *
     * @param user
     * @return
     */
    @PutMapping(value = "/update")
    @Permission
    @BussinessLog(value = "修改用户", key = "user")
    public CommRes update(@RequestBody User user) {
        if (ShiroKit.hasRole(Const.ADMIN_NAME)) {
            userDao.save(user);
            return CommRes.successRes();
        } else {
            assertAuth(user.getId());
            ShiroUser shiroUser = ShiroKit.getUser();
            if (shiroUser.getId().equals(user.getId())) {
                userDao.save(user);
                return CommRes.successRes();
            } else {
                throw new BussinessException(BizExceptionEnum.NO_PERMITION);
            }
        }
    }

    /**
     * 删除用户
     *
     * @param userId
     * @return
     */
    @DeleteMapping(value = "/delete/{userId}")
    @Permission
    @BussinessLog(value = "删除用户", key = "userId")
    public CommRes delete(@PathVariable("userId") Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new BussinessException(BizExceptionEnum.REQUEST_NULL);
        }
        //不能删除超级管理员
        if (userId.equals(Const.ADMIN_ID)) {
            throw new BussinessException(BizExceptionEnum.CANT_DELETE_ADMIN);
        }
        assertAuth(userId);
        userDao.delete(userId);
        return CommRes.successRes();
    }

    /**
     * 冻结用户
     *
     * @param userId
     * @return
     */
    @PutMapping(value = "/freeze/{userId}")
    @Permission(Const.ADMIN_NAME)
    @BussinessLog(value = "冻结用户", key = "userId")
    public CommRes freeze(@PathVariable("userId") Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new BussinessException(BizExceptionEnum.REQUEST_NULL);
        }
        //不能冻结超级管理员
        if (userId.equals(Const.ADMIN_ID)) {
            throw new BussinessException(BizExceptionEnum.CANT_FREEZE_ADMIN);
        }
        assertAuth(userId);
        userDao.setStatus(userId, UserStatus.FREEZED.getCode());
        return CommRes.successRes();
    }

    /**
     * 解除用户冻结
     *
     * @param userId
     * @return
     */
    @PutMapping(value = "/unfreeze/{userId}")
    @Permission(Const.ADMIN_NAME)
    @BussinessLog(value = "解除冻结用户", key = "userId")
    public CommRes unfreeze(@PathVariable("userId") Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new BussinessException(BizExceptionEnum.REQUEST_NULL);
        }
        assertAuth(userId);
        userDao.setStatus(userId, UserStatus.OK.getCode());
        return CommRes.successRes();
    }

    /**
     * 用户角色分配
     *
     * @param userId
     * @param requestParams
     * @return
     */
    @PostMapping(value = "/setRole/{userId}")
    @Permission(Const.ADMIN_NAME)
    @BussinessLog(value = "分配角色", key = "userId")
    public CommRes setRole(@PathVariable Integer userId, @RequestBody RequestParams requestParams) {
        if (ToolUtil.isOneEmpty(requestParams.getRoleid())) {
            throw new BussinessException(BizExceptionEnum.REQUEST_NULL);
        }
        //不能修改超级管理员
        if (userId.equals(Const.ADMIN_ID)) {
            throw new BussinessException(BizExceptionEnum.CANT_CHANGE_ADMIN);
        }
        assertAuth(userId);
        userDao.setRoles(userId, requestParams.getRoleid());
        return CommRes.successRes();
    }

    /**
     * 修改当前用户密码
     *
     * @return
     */
    @PostMapping("/changePwd")
    @BussinessLog(value = "修改当前用户密码", key = "userId")
    public CommRes changePwd(@RequestBody RequestParams requestParams) {
        if (!requestParams.getNewPassword().equals(requestParams.getRePassword())) {
            throw new BussinessException(BizExceptionEnum.TWO_PWD_NOT_MATCH);
        }
        Integer userId = ShiroKit.getUser().getId();
        User user = userDao.findOne(userId);
        String oldMd5 = ShiroKit.md5(requestParams.getOldPassword(), user.getSalt());
        if (user.getPassword().equals(oldMd5)) {
            String newMd5 = ShiroKit.md5(requestParams.getNewPassword(), user.getSalt());
            user.setPassword(newMd5);
            userDao.save(user);
            return CommRes.successRes();
        } else {
            throw new BussinessException(BizExceptionEnum.OLD_PWD_NOT_RIGHT);
        }
    }

    /**
     * 重置用户密码
     *
     * @param userId
     * @return
     */
    @PostMapping("/resetPassword/{userId}")
    @Permission(Const.ADMIN_NAME)
    @BussinessLog(value = "重置用户密码", key = "userId")
    public CommRes reset(@PathVariable Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new BussinessException(BizExceptionEnum.REQUEST_NULL);
        }
        assertAuth(userId);
        User user = userDao.findOne(userId);
        user.setSalt(ShiroKit.getRandomSalt(5));
        user.setPassword(ShiroKit.md5(Const.DEFAULT_PWD, user.getSalt()));
        userDao.save(user);
        return CommRes.successRes();
    }

    /**
     * 判断当前登录的用户是否有操作这个用户的权限
     *
     * @param userId
     */
    private void assertAuth(Integer userId) {
        if (ShiroKit.isAdmin()) {
            return;
        }
        List<Integer> deptDataScope = ShiroKit.getDeptDataScope();
        User user = userDao.findOne(userId);
        Integer deptid = user.getDeptid();
        if (deptDataScope.contains(deptid)) {
            return;
        } else {
            throw new BussinessException(BizExceptionEnum.NO_PERMITION);
        }
    }
}
